package com.xhwl.centiotdata.suppliersystem.guangtuo.alarmhost.websocket.handle.event;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.device.impl.DeviceIntegrationGuangTuoHandler;
import com.xhwl.centiotdata.pojo.dto.alarmhost.AlarmHostIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.dto.alarmhost.DeviceGuangTuoAlarmHostDTO;
import com.xhwl.centiotdata.pojo.dto.alarmhost.DeviceStatusGuangTuoAlarmHostDTO;
import com.xhwl.centiotdata.pojo.dto.alarmhost.DeviceSubSystemStatusGuangTuoAlarmHostDTO;
import com.xhwl.centiotdata.pojo.dto.device.DeviceIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.integrateconfig.AlarmHostIntegrationConfig;
import com.xhwl.centiotdata.suppliersystem.guangtuo.DeviceGuangTuoAlarmHostHandler;
import com.xhwl.centiotdata.suppliersystem.guangtuo.alarmhost.websocket.handle.AlarmHostNotifyHandle;
import com.xhwl.centiotdata.suppliersystem.guangtuo.alarmhost.websocket.handle.AlarmHostNotifyHandleFactory;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import com.xhwl.common.query.cent.device.DeviceQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author zyz
 * @date 2023-04-26
 * 报警主机资源变更通知处理
 */
@Slf4j
@Service
public class AlarmHostResourceNotifyHandle extends AlarmHostNotifyHandle {
    private static final String TOPIC = "/ws/alarmhost/v2/notification/resource";

    private static final String CREATE_STATUS_FLAG = "created";

    private static final String UPDATE_STATUS_FLAG = "updated";

    private static final String DELETE_STATUS_FLAG = "deleted";

    @Value("${guangTuo.alarmhost.ipAndPort:-1}")
    private String ipAndPort;

    @Resource
    private IDeviceCentService deviceCentService;

    @Resource
    private AlarmHostIntegrationConfig integrationConfig;

    @Resource
    private DeviceGuangTuoAlarmHostHandler deviceGuangTuoAlarmHostHandler;


    @Override
    public void afterPropertiesSet() throws Exception {
        AlarmHostNotifyHandleFactory.register(TOPIC, this);
    }

    @Override
    public void handler(String status, String data) {
        log.info("websocket-报警主机资源变更通知处理  TOPIC={},status={},data={}", TOPIC, status, data);
        DeviceGuangTuoAlarmHostDTO deviceGuangTuoAlarmHostDTO = JSONObject.parseObject(data, DeviceGuangTuoAlarmHostDTO.class);
        if (null == deviceGuangTuoAlarmHostDTO) {
            log.error("websocket  TOPIC={},status={},报警主机资源变更通知序列化失败", TOPIC, status);
            return;
        }
        String objID = deviceGuangTuoAlarmHostDTO.getObjID();
        if (DELETE_STATUS_FLAG.equals(status)){
            DevicePageQuery deviceQuery = new DevicePageQuery();
            deviceQuery.setJsonFieldName("objID");
            deviceQuery.setDeviceTypeId(CategoryEnum.ALARM_HOST_SYSTEM.getId());
            deviceQuery.setJsonFieldValue(objID);
            List<DeviceDTO> deviceDTOList = deviceCentService.listDevice(null, deviceQuery);
            if (!CollectionUtils.isEmpty(deviceDTOList)){
                for (DeviceDTO deviceDTO : deviceDTOList) {
                    DeviceQuery deviceDeleteDTO=new DeviceQuery();
                    BeanUtils.copyProperties(deviceDTO, deviceDeleteDTO);
                    deviceCentService.deleteByIotIdV2(deviceDeleteDTO);
                }
            }
            return;
        }
        Map<Integer, List<AlarmHostIntegrationConfigDTO>> integrationConfigDTOMap = this.integrationConfig.getIntegrationConfig(null);
        log.info("获取的报警主机项目集成配置信息:{}", integrationConfigDTOMap);
        integrationConfigDTOMap.forEach((k, v) -> {
            int size = v.size();
            if (size == 1) {
                AlarmHostIntegrationConfigDTO alarmHostIntegrationConfigDTO = v.get(0);
                DeviceIntegrationConfigDTO configDTO = new DeviceIntegrationConfigDTO();
                BeanUtils.copyProperties(alarmHostIntegrationConfigDTO, configDTO);
                configDTO.setDeviceType(CategoryEnum.ALARM_HOST_SYSTEM.getId());
                configDTO.setCategoryEnum(CategoryEnum.ALARM_HOST_SYSTEM);
                List<DeviceStatusGuangTuoAlarmHostDTO> deviceStatusGuangTuoAlarmHostDTOList = deviceGuangTuoAlarmHostHandler.pullDeviceStatusByObjId(ipAndPort, objID);
                if (CollectionUtils.isEmpty(deviceStatusGuangTuoAlarmHostDTOList)) {
                    log.error("websocket  TOPIC={},status={},objID={} 报警主机资源变更通知防区无状态信息", TOPIC, status, objID);
                    return;
                }
                List<DeviceSubSystemStatusGuangTuoAlarmHostDTO> deviceSubSystemStatusGuangTuoAlarmHostDTOList = deviceGuangTuoAlarmHostHandler.pullDeviceSubSystemStatusList(configDTO);
                if (CollectionUtils.isEmpty(deviceSubSystemStatusGuangTuoAlarmHostDTOList)) {
                    deviceSubSystemStatusGuangTuoAlarmHostDTOList = new ArrayList<>();
                }
                List<DeviceDTO> deviceDTOList = DeviceIntegrationGuangTuoHandler.handleDevice(configDTO, Arrays.asList(deviceGuangTuoAlarmHostDTO), deviceStatusGuangTuoAlarmHostDTOList, deviceSubSystemStatusGuangTuoAlarmHostDTOList);
                switch (status) {
                    case CREATE_STATUS_FLAG:
                        deviceCentService.asyncUpdateDevice(deviceDTOList);
                        break;
                    case UPDATE_STATUS_FLAG:
                        ResultJson resultJson = deviceCentService.batchUpdate(null, deviceDTOList);
                        log.info("websocket-报警主机资源变更通知修改结果:{}", JSON.toJSONString(resultJson));
                        break;
                    default:
                        break;
                }
            } else {
                log.error("该项目具有多个集成配置，因此该项目不会做任何逻辑行为，项目id：{}", k);
            }
        });

    }
}
